#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>


/**
 * @brief 主函数，用于打开文件、获取文件大小、扩展文件、映射文件到内存、修改内存内容并同步到文件。
 *
 * @return int 程序执行状态，0表示成功，1表示失败。
 */
int main() {
    // 打开文件 "file2.txt" 以读写模式
    int fd = open("file2.txt", O_RDWR);
    // 如果文件打开失败，输出错误信息并返回1
    if (fd == -1) {
        perror("open");
        return 1;
    }

    // 定义一个stat结构体用于存储文件信息
    struct stat st;
    // 获取文件信息，如果失败，输出错误信息，关闭文件并返回1
    if (fstat(fd, &st) == -1) {
        perror("fstat");
        close(fd);
        return 1;
    }
    // 获取文件大小
    off_t fileSize = st.st_size;

    // 定义偏移量和长度
    off_t offset = 3;
    size_t length = fileSize - offset;
    // 打印文件大小、偏移量和长度
    printf("fileSize = %ld, offset = %ld, length = %ld\n", fileSize, offset, length);
    printf("run to here 1\n");

    // 扩展文件大小，增加"World"字符串长度和一个终止符

    if (ftruncate(fd, fileSize + strlen("World") + 1) == -1) {
        perror("ftruncate");
        close(fd);
        return 1;
    }

    // 将文件映射到内存，如果失败，输出错误信息，关闭文件并返回1

    char *map = mmap(NULL, fileSize + strlen("World") + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (map == MAP_FAILED) {
        perror("mmap");
        close(fd);
        return 1;
    }
    printf("run to here 2\n");

    // 在文件末尾添加字符串"World"

    strcpy(map + fileSize, "World");

    // 将内存中的修改同步到文件，如果失败，输出错误信息，解除映射并关闭文件
    if (msync(map, fileSize + strlen("World") + 1, MS_SYNC) == -1) {
        perror("msync");
        munmap(map, fileSize + strlen("World") + 1);
        close(fd);
        return 1;
    }

    // 解除文件映射
    munmap(map, fileSize + strlen("World") + 1);
    // 关闭文件
    close(fd);
    // 返回0表示程序执行成功
    return 0;
}

